package essential;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.vecmath.*;
import main.Raycast;

public class RayCaster {

	public int THREADS_COUNT = 1;

	BufferedImage m_Dest;
	static int m_Width, m_Height;
	boolean logCV;
	private static boolean randColor;
	
	private static int increase = 0;
	
	static boolean MOTION_BLUR = true;
	static int     motionBlurDt = 3;
	
	public RayCaster(Scene scene, Camera camera, boolean logCV, boolean randColor){
		Render.camera = camera;
		Render.m_Dest = m_Dest;
		Render.scene = scene;
		Render.antialiasing = scene.aaMax > 0;
		Render.antiAliasingMinDepth = scene.aaMin;
		Render.antiAliasingMaxDepth = scene.aaMax;
		RayCaster.setRandColor(randColor);
		
		if(scene.threadsCount > 0)
			THREADS_COUNT = scene.threadsCount;
	}
	
	public void setTarget(BufferedImage outImage, int width, int height){
		
		Render.m_Dest = outImage;
		m_Width =  Render.m_Width = width;
		m_Height = Render.m_Height = height;
		
		this.m_Dest = outImage;
	
		outImage.createGraphics();
	}

	static public void IncreaseProgress(){

		if(Raycast.progress ){
			increase++;

				if(MOTION_BLUR == false){
					if( increase % 100 == 0)
					System.out.println("Progress "+ increase*100/m_Width + "% Done");
				}else{
					if( increase % 250 == 0)
					System.out.println("Progress "+ increase*100/(m_Width*motionBlurDt) + "% Done");
				}
		}
	}

	public boolean Render(){
	
    	
		
		int counter = 0;
	
		System.out.println("Starting rendering with "+THREADS_COUNT+" threads");

		do{
			
		int yCant = m_Height/THREADS_COUNT;
		int yRest = m_Height%THREADS_COUNT;
		int yCounter = 0;
		
		ArrayList<Render> v = new ArrayList<Render>();

		
		Vector3d origin = new Vector3d(Render.camera.origin);
		
		for ( int i = 0; i < THREADS_COUNT-1; i++ )
		{
				Render r = new Render(0,m_Width,yCounter,yCounter+yCant);
				r.setPriority(Thread.MAX_PRIORITY);
				r.start();
				v.add(r);
				
				yCounter+= yCant;
		}
		
		Render r = new Render(0,m_Width,yCounter,yCounter+yCant+yRest);
		r.setPriority(Thread.MAX_PRIORITY);
		r.start();
		v.add(r);

		for( int i = 0; i < v.size(); i++) {
			try{
				v.get(i).join();
			}catch(Exception e){
				e.printStackTrace();
				return false;
			};
		}
		
		// Move the camera in a custom way for Motion Blur
	//	origin.x += 2*Math.sin(Math.random());
	//	origin.y += 2*Math.sin(Math.random());;
	//	origin.z -= 0.3;

		Render.scene.lightRenderables.get(0); 
		Render.camera.origin = origin;
		
		}while(MOTION_BLUR && counter++ != motionBlurDt );
	

		

		if( Raycast.progress )
		System.out.println("Progress 100% Done");
		
		return true;
	}
	
	public static void setRandColor(boolean randColor) {
		RayCaster.randColor = randColor;
	}

	public static boolean isColorRandom() {
		return randColor;
	}

}
